<?php
/** ================================
 *  Intellect Board 3
 *  http://intblite.ru
 *  Модуль отображения темы стандартного форума
 *
 *  ================================ */

require_once('modules/uniforum.php');

class topic extends UniForum {

  function  __construct($data=false,$mode=0) {
    parent::__construct($data, $mode);
    $this->data['type_id']=65;
  }

  /** Просмотр темы обычного форума.
   *
   * @param int $page Номер текущей страницы
   *
   * Действия:
   *
   */
  function action_view($page=1) {
    global $app;

    $totals = $this->data['posts']; // количество отображаемых сообщений в теме
    $direction = $this->get_opt_recursive('topic_direction',0);  // направление сортировки (по умолчанию сортировка прямая)
    $perpage = $this->get_opt_recursive('topic_perpage',20); // количество сообщений на странице
    $pagedata = $this->get_pages($totals,$page,$perpage,$direction); // формируем информацию о страницах, смещении и кол-ве страниц

    if ($pagedata===false) return false;

    $result = new Html('topic','topic');
    $result->set('data',$this->data); // выводим общую информация о теме
    $result->set('pagedata',$pagedata); // выводим информацию о разбиении на страницы

    $posts=$this->get_posts($pagedata['start'],$pagedata['perpage']);
    for ($i=0, $count=count($posts); $i<$count; $i++) { // распаковываем сериализованные данные из кеша пользователя
      if (isset($posts[$i]['usercache']) && $posts['usercache']) $posts[$i]['userdata']=unserialize($posts[$i]['usercache']);
//      else $posts[$i]['userdata']=$app->user->load_guest();
    }
    $result->set('posts',$posts); // получаем и выводим сами сообщения

    $this->fix_view(); // фиксируем просмотр темы пользователем (увеличение счетчика, фиксация даты последнего просмотра и т.п.)

    // Проверка модераторских действий
    $moderate=$app->user->check_access('moderate');
    $result->set('moderate',$moderate);
    //TODO: получение кол-ва сообщений на премодерации и в корзине

    //TODO: подумать, как сделать вывод объявлений
    //TODO: ссылка на правила форума
    //TODO: вывод опроса, если есть

    // показ кнопок ответа и новой темы, если у пользователя есть права
    $rights['newtopic'] = $app->user->check_access('newobject');
    $rights['newpost'] = $app->user->check_access('post');
    $rights['moderate'] = $app->user->check_access('moderate');
    $rights['edit'] = $app->user->check_access('editpost');
    $rights['complain'] = $app->user->check_access('complain');
    $rights['delete'] = $app->user->check_access('deletepost');
    $result->set('rights',$rights);
    $result->set('uid',$app->user->get_uid());

    $showform=$this->get_opt_recursive('topic_showform',1);
    if ($showform) {
      $post=$this->set_post();
      $result->set('post',$post);
    }
    $result->set('showform',$showform); // показывать ли форму быстрого ответа

    return $result;
  }

  /** Вывод формы для отправки сообщения и сама отправка. **/
  function action_reply() {
    global $app;
    $errors=array();
    if ($app->is_post()) { // если форма с сообщением уже отправлена и нужно ее обработать
      $data=$this->set_post($_POST['post'],1); // если уже отправляли форму и возникли ошибки
      unset($data['id']); // сбрасываем идентификатор, у нового сообщения его быть не должно
      $errors=$this->validate_post($data);
      if (empty($errors)) { // если при проверке допустимости сообщения не возникло ошибок
        $this->save_post($data,1);  // сохраняем сообщение, если нет ошибок, вызываем процедуру обновления родительских объектов
        $time=time();
        $this->update_objects($app->objparents,$time,1,0);
          // TODO: обработка подписок и рассылок тем, кто подписан на немедленные уведомления
        $app->message('Сообщение успешно отправлено!',1);
        $app->status=302;
        $app->location=$app->hurl($this->data['url'].'/last.htm'); // переходим на last.htm, чтобы потом не было проблем с двойной отправкой при обновлении. TODO: подумать о доделке, чтобы не было двойного 302.
        return;
      }
    }
    else $data=$this->set_post(false); // иначе выставляем значения по умолчанию
    $result = new Html('reply','topic');
    $result->set('post',$data);
    $result->set('data',$this->data);
    $result->set('errors',$errors);
    // TODO: передать наличие модераторских прав
    $posts=$this->get_posts(0,10,true);
    $result->set('posts',$posts);
    return $result;
  }

  /** Редирект на последнее сообщение **/
  function action_last() {
    global $app;
    $direction = $this->get_opt_recursive('topic_direction',0);  // направление сортировки (по умолчанию сортировка прямая)

    if (!$direction) $offset=$this->data['posts']-1;
    else $offset=0;
    $link = $this->get_page_link($offset,$direction);

    $app->status=302;
    $app->location=$link;
    return false;
  }

  /** Редирект на конкретное сообщение **/
  function action_post() {
    global $app;
    $pid = intval($_REQUEST['id']);

    $postdata=$this->get_post_by_id($pid);
    if (!$postdata){
      $app->status=404;
      $app->mode=1;
      $app->message('Не найдено сообщение с указанным номером!',3);
      return false;
    }

    $direction = $this->get_opt_recursive('topic_direction',0);  // направление сортировки (по умолчанию сортировка прямая)
    $offset=$this->get_post_offset($postdata['oid'], $postdata['postdate'],$direction);
    $link = $this->get_page_link($offset,$direction).'#post'.$postdata['id'];


    $app->status=302;
    $app->location=$link;
    return false;
  }

  /** Редирект на первое новое сообщение в теме **/
  function action_new() {
    global $app;
    
    if ($app->user->is_guest()) { // если пользователь -- гость, выдаем ошибку
      $app->status=403;
      $app->mode=1;
      $app->message('Гостям не доступна функция отслеживания новых сообщений!',3);
      $app->location=$app->hurl($this->data['url']); // и отправляем пользователя на первую страницу
      return false;      
    }
    $sql = 'SELECT visit1 FROM '.DB_prefix.'object_visit WHERE oid='.intval($this->data['id']).' AND uid='.intval($app->user->get_uid()); //TODO: подумать, что нужно: visit1 или visit2
    $lastvisit = $app->db->select_int($sql);

    $direction = $this->get_opt_recursive('topic_direction',0);  // направление сортировки (по умолчанию сортировка прямая)
    $offset=$this->get_post_offset($this->data['id'], $lastvisit,$direction);
    $link = $this->get_page_link($offset,$direction);

    $app->status=302;
    $app->location=$link;
    return false;
  }

  /** Редактирование уже отправленного сообщения **/
  function action_edit() {
    global $app;

    if (!isset($_REQUEST['id']) || !$_REQUEST['id']) { // если не указан номер сообщения
      $app->status=404;
      $app->mode=1;
      $app->message('Не указан номер сообщения для редактирования!',3);
      return false;
    }

    $pid = intval($_REQUEST['id']);
    
    $postdata=$this->get_post_by_id($pid);
    if (!$postdata){
      $app->status=404;
      $app->mode=1;
      $app->message('Не найдено сообщение с указанным номером!',3);
      return false;
    }

    if ($postdata['uid']==$app->user->get_uid()) $owner=true; // проверяем, является ли текущий пользователь является владельцем сообщения (это потребуется при проверке прав на редактирование)
    else $owner=false;
    $moderator=$app->user->check_access('moderate');

    if (!$owner) { // если пользователь не является автором сообщения, проверяем, является ли он модератором
      if (!$moderator) {
        $app->status=403;
        $app->mode=1;
        $app->message('У вас нет модераторских прав, поэтому вы не можете редактировать чужие сообщения!',3);
        return false;
      }
    }
    else {
      if (!$app->user->check_access('edit')) {
        $app->status=403;
        $app->mode=1;
        $app->message('У вас нет прав на редактирование сообщений!',3);
        return false;
      }
      if ($postdata['locked']) {
          $app->status=403;
          $app->mode=1;
          $app->message('Редактирование сообщения запрещено модератором!',3);
          return false;
      }
      $edittime = $app->get_opt('post_edittime'); // получаем из настроек количество минут, в течение которого можно редактировать сообщение
      if ($edittime) { // если это время не равно нулю, выполняем проверку
        $time = time();
        if ($postdata['postdate']<$time-$edittime*60) {
          $app->status=403;
          $app->mode=1;
          $app->message('После отправки сообщения прошло более '.$edittime.' минут, редактирование запрещено!',3);
          return false;
        }
      }
    }

    if ($app->is_post()) {
      $data=$this->set_post($_POST['post'],1); // если уже отправляли форму и возникли ошибки
      $data['id']=$pid;
      $errors=$this->validate_post($data);
      if ($moderator) { // если есть модераторские права, проверяем дополнительные опции: закрытие сообщения и комментарий модератора
        if (isset($_POST['post']['locked'])) $data['locked']=1;
        if (isset($_POST['post']['text2'])) $data['text2']=$_POST['post']['text2'];
      }
      if (empty($errors)) { // если при проверке допустимости сообщения не возникло ошибок
        $this->save_post($data,1);  // сохраняем сообщение, если нет ошибок, вызываем процедуру обновления родительских объектов
        $time=time();
        $this->update_objects(array($this),$time,0,0); // обновляем только текущий объект и только время последней модификации, счетчик сообщений остается неизменным
        $app->message('Сообщение успешно отредактировано!',1);
        $app->status=302;
        $app->location=$app->hurl($this->data['url'].'/last.htm'); // переходим на last.htm, чтобы потом не было проблем с двойной отправкой при обновлении. TODO: подумать о доделке, чтобы не было двойного 302.
        return;
      }
    }
    else $errors=array();
    $result = new Html('reply','topic');
    $result->set('post',$postdata);
    $result->set('data',$this->data);
    $result->set('errors',$errors);
    return $result;
  }

  /** Описание текущего действия в строке навигации **/
  function get_location($action) {
    if ($action=='reply') return 'Отправка ответа';
    elseif ($action=='edit') return 'Редактирование сообщения';
    else return false;
  }

}

?>
